package com.yilin.tms.user.controller;

import com.google.gson.reflect.TypeToken;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.FieldUtil;
import com.yilin.commons.util.JsonUtil;
import com.yilin.tms.core.commons.constant.IncrementConstant;
import com.yilin.tms.core.application.ReturnData;
import com.yilin.tms.core.commons.base.BaseController;
import com.yilin.tms.core.entity.system.system.FunctionApi;
import com.yilin.tms.core.entity.system.system.Menu;
import com.yilin.tms.core.entity.user.RoleType;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.organize.MemberType;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.core.entity.user.organize.UserRole;
import com.yilin.tms.user.service.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 权限模块
 * 账户授权管理
 */
@RestController
@RequestMapping("/user/grant/")
public class GrantController extends BaseController {

    @Resource
    IOrganizeService organizeService;
    @Resource
    IMemberTypeService memberTypeService;
    @Resource
    IRoleService roleService;
    @Resource
    IGrantFunctionApiService grantFunctionApiService;
    @Resource
    IGrantMenuService grantMenuService;
    @Resource
    IGrantRoleMenuService grantRoleMenuService;

    /**
     * 【NO.1:组织功能授权】
     * {指定会员} 查看API授权列表
     */
    @PostMapping("getGrantFunctionApiList")
    public ReturnData<Object> getGrantFunctionApiList(String memberTypeId) {
        if (memberTypeId == null) {
            Organize organize = organizeService.getOrganizeById(getLoginUser().getOrganizeId());
            memberTypeId = organize.getMemberTypeId();
        }
        List<FunctionApi> functionApiList = grantFunctionApiService.getGrantFunctionApiList(memberTypeId);
        return jsonView(true, "获取列表成功！", functionApiList);
    }

    /**
     * 【NO.1:会员API授权】
     * 查看API授权列表
     */
    @PostMapping("getGrantFunctionApiTree")
    public ReturnData<Object> getGrantFunctionApiTree(String memberTypeId) {
        if (memberTypeId == null) {
            return jsonView(false, "未知数据ID！");
        }
        MemberType memberType = memberTypeService.getMemberTypeById(getLoginUser().getOrganizeId(), memberTypeId);
        if (memberType == null) {
            return jsonView(false, "你的组织下没有找到会员类型！");
        }
        //获取自己拥有的API权限
        List<FunctionApi> functionApiList = grantFunctionApiService.getMineGrantFunctionApiList(memberType.getOrganizeId());
        if (functionApiList == null) {
            return jsonView(false, "抱歉，你还没有任何权限，请联系您的上级平台授予您相关权限！");
        }
        //获取已授权功能权限
        List<String> grantCodeList = grantFunctionApiService.getGrantFunctionApiCodeList(memberTypeId);
        //进行嫁接，存放权限选中状态
        Map<String, Object> checkedMap = new HashMap<>();
        checkedMap.put("functionApiList", functionApiList);
        checkedMap.put("grantCodeList", grantCodeList);
        return jsonView(true, "获取列表成功！", checkedMap);
    }

    /**
     * 【NO.1:会员API授权】
     * 更新API授权列表
     */
    @PostMapping("updateGrantFunctionApiList")
    public ReturnData<Object> updateGrantMemberTypeFunctionApiList(String memberTypeId, String[] apiCodes) {
        if (memberTypeId == null) return jsonView(false, "未知数据ID！");
        if (apiCodes == null) return jsonView(false, "权限设置错误！");
        MemberType memberType = memberTypeService.getMemberTypeById(getLoginUser().getOrganizeId(), memberTypeId);
        if (memberType == null) {
            return jsonView(false, "你的组织下没有找到会员类型！");
        }
        //获取自己拥有的API权限
        List<String> functionApiList = grantFunctionApiService.getMineGrantFunctionApiCodeList(memberType.getOrganizeId());
        for (String functionApiCode : apiCodes) {
            if (!functionApiList.contains(functionApiCode)) return jsonView(false, "权限验证失败！");
        }
        grantFunctionApiService.updateGrantFunctionApiList(memberTypeId, apiCodes);
        return jsonView(true, "授权更新成功！");
    }

    /**
     * 【NO.2:组织菜单授权】
     * {指定会员} 查看菜单授权列表 树
     */
    @PostMapping("getGrantMenuList")
    public ReturnData<Object> getGrantMenuList(String memberTypeId) {
        UserType userType = getLoginUser().getUserType();
        if (memberTypeId == null) {
            Organize organize = organizeService.getOrganizeById(getLoginUser().getOrganizeId());
            userType = organize.getUserType();
            memberTypeId = organize.getMemberTypeId();
        }
        /// 获取对应会员的菜单及其操作信息
        List<Menu> menuList = grantMenuService.getGrantMenuOperateList(userType, memberTypeId);
        return jsonView(true, "获取列表成功！", menuList);
    }

    /**
     * 【NO.2:会员菜单授权】
     * 查看菜单授权列表
     */
    @PostMapping("getGrantMenuTree")
    public ReturnData<Object> getGrantMenuTree(String memberTypeId) {
        if (memberTypeId == null) return jsonView(false, "未知数据ID！");
        MemberType memberType = memberTypeService.getMemberTypeById(getLoginUser().getOrganizeId(), memberTypeId);
        if (memberType == null) return jsonView(false, "你的组织下没有找到会员类型！");
        Organize mineOrganize = organizeService.getOrganizeById(getLoginUser().getOrganizeId());
        /// 获自己拥有的菜单及其操作权限信息
        List<Menu> menuList = grantMenuService.getGrantMenuOperateList(mineOrganize.getUserType(), mineOrganize.getMemberTypeId());
        /// 获取已对该会员的授权权限
        Map<String, List<String>> authorityMap = new HashMap<>();
        List<String> grantCodeList = grantMenuService.getGrantMenuCodeList(memberTypeId);
        for (String grantCode : grantCodeList) {
            List<String> grantMenuOperateCodeList = grantMenuService.getGrantMenuOperateCodeList(memberTypeId, grantCode);
            authorityMap.put(grantCode, grantMenuOperateCodeList);
        }
        //进行嫁接，存放权限选中状态
        Map<String, Object> checkedMap = new HashMap<>();
        checkedMap.put("menuList", menuList);
        checkedMap.put("authorityMap", authorityMap);
        return jsonView(true, "获取列表成功！", checkedMap);
    }

    /**
     * 【NO.2:会员菜单授权】
     * 更新菜单授权列表
     * 前台传值格式 {"menuCode1:[operateCode1,operateCode2]","menuCode2:[operateCode3,operateCode4]",...}
     */
    @PostMapping("updateGrantMenuList")
    public ReturnData<Object> updateGrantMenuList(String memberTypeId, String authorityMapJson) {
        if (memberTypeId == null || authorityMapJson == null) return jsonView(false, "权限设置错误！");
        MemberType memberType = memberTypeService.getMemberTypeById(getLoginUser().getOrganizeId(), memberTypeId);
        if (memberType == null) return jsonView(false, "你的组织下没有找到会员类型！");
        Map<String, String[]> authorityMap = JsonUtil.jsonToObject(authorityMapJson, new TypeToken<Map<String, String[]>>() {
        });
        Organize mineOrganize = organizeService.getOrganizeById(getLoginUser().getOrganizeId());
        authorityMap = grantMenuService.checkAuthorityMap(mineOrganize.getUserType(), mineOrganize.getMemberTypeId(), authorityMap);
        grantMenuService.updateGrantMenuList(memberTypeId, authorityMap);
        return jsonView(true, "授权更新成功！");
    }

    /**
     * 【NO.3:角色菜单】
     * {当前} 查看角色菜单
     */
    @PostMapping("getGrantRoleMenuTree")
    public ReturnData<Object> getGrantRoleMenuTree() {
        ///<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<前台主菜单列表核心方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//        List<Menu> menuList = grantRoleMenuService.getGrantRoleMenuOperateList(getLoginUser().getUserType(), getLoginUser().getRoleId());
        return jsonView(true, "获取列表成功！", null);
    }

    /**
     * 【NO.3:角色菜单授权】
     * 查看菜单授权列表
     */
    @PostMapping("getGrantRoleMenuList")
    public ReturnData<Object> getGrantRoleMenuList(String roleId) {
        if (roleId == null) return jsonView(false, "不知道角色！");
        if (getLoginUser().getUserType() != UserType.adminUser && getLoginUser().getRoleType() != RoleType.manager) {
            return jsonView(false, "您不是管理员不能查看角色权限信息！");
        }
        UserRole userRole = roleService.getUserRoleById(getLoginUser().getOrganizeId(), roleId);
        //获取组织拥有的所有权限
        Organize organize = organizeService.getOrganizeById(userRole.getOrganizeId());
        List<Menu> menuList = grantMenuService.getGrantMenuOperateList(organize.getUserType(), organize.getMemberTypeId());
        //获取已授权权限
        Map<String, List<String>> authorityMap = new HashMap<>();
        List<String> grantCodeList = grantRoleMenuService.getGrantRoleMenuCodeList(userRole.getId());
        for (String grantCode : grantCodeList) {
            List<String> grantMenuOperateCodeList = grantRoleMenuService.getGrantRoleMenuOperateCodeList(roleId, grantCode);
            authorityMap.put(grantCode, grantMenuOperateCodeList);
        }
        //进行嫁接，存放权限选中状态
        Map<String, Object> checkedMap = new HashMap<>();
        checkedMap.put("menuList", menuList);
        checkedMap.put("authorityMap", authorityMap);
        return jsonView(true, "获取列表成功！", checkedMap);
    }

    /**
     * 【NO.3:角色菜单授权】
     * 更新菜单授权列表
     * 前台传值格式 ["menuCode1:operateCode1&operateCode2","menuCode2:operateCode3&operateCode4",...]
     */
    @PostMapping("updateGrantRoleMenuList")
    public ReturnData<Object> updateGrantRoleMenuList(String roleId, String authorityMapJson) {
        if (authorityMapJson == null) return jsonView(false, "权限设置错误！");
        if (getLoginUser().getRoleType() != RoleType.manager) {
            return jsonView(false, "您不是管理员不能管理角色权限信息！");
        }
        Map<String, String[]> authorityMap = JsonUtil.jsonToObject(authorityMapJson, new TypeToken<Map<String, String[]>>() {
        });
        UserRole userRole = roleService.getUserRoleById(getLoginUser().getOrganizeId(), roleId);
        if (userRole == null) return jsonView(false, "组织下没有角色，或者您可能没有操作权限！");
        //获取组织拥有的所有权限
        Organize mineOrganize = organizeService.getOrganizeById(getLoginUser().getOrganizeId());
        authorityMap = grantMenuService.checkAuthorityMap(mineOrganize.getUserType(), mineOrganize.getMemberTypeId(), authorityMap);
        grantRoleMenuService.updateGrantRoleMenuList(roleId, authorityMap);
        return jsonView(true, "授权更新成功！");
    }

    /**
     * 【NO.3:获取会员+功能权限列表】
     */
    @PostMapping(value = "getMyMemberTypeConfig")
    public ReturnData<MemberType> getMyMemberTypeConfig(String organizeId) {
        MemberType memberType;
        if (organizeId != null) memberType = memberTypeService.getMyMemberType(organizeId);
        else memberType = memberTypeService.getMyMemberType(getLoginUser().getOrganizeId());

        /// ### 查看發佈方案 支持
        List<FunctionApi> functionApiList = grantFunctionApiService.getMineGrantFunctionApiList(memberType.getOrganizeId());
        /// ### 自定筛选属性对象并判空，返回的为非空属性集合
        List<String> objectList = ArrayUtil.fieldAdd(functionApiList, FunctionApi::getCode);
        /// ### 获取查询字段
        Map<String, String> paramMap = new HashMap<>();
        for (Field field : FieldUtil.getFields(IncrementConstant.class)) {
            paramMap.put(field.getName(), (String) FieldUtil.objGet(new IncrementConstant(), field));
        }
        /// ### 功能查存
        Map<String, Boolean> incrementMap = new HashMap<>();
        for (String key : paramMap.keySet()) {
            incrementMap.put(key, objectList.contains(paramMap.get(key)));
        }
        memberType.setIncrementMap(incrementMap);
        return jsonView(true, "获取功能权限成功！", memberType);
    }


}
